package com.platform.modules.wallet.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.mail.MailUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.platform.common.constant.AppConstants;
import com.platform.common.utils.redis.RedisUtils;
import com.platform.common.web.service.impl.BaseServiceImpl;
import com.platform.modules.chat.domain.ChatUser;
import com.platform.modules.chat.service.ChatUserService;
import com.platform.modules.wallet.dao.WalletDailyBillDao;
import com.platform.modules.wallet.domain.Wallet;
import com.platform.modules.wallet.domain.WalletAccount;
import com.platform.modules.wallet.domain.WalletDailyBill;
import com.platform.modules.wallet.service.WalletAccountService;
import com.platform.modules.wallet.service.WalletAlarmService;
import com.platform.modules.wallet.service.WalletDailyBillhService;
import com.platform.modules.wallet.service.WalletService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.sql.SQLException;
import java.sql.SQLIntegrityConstraintViolationException;
import java.util.Date;
import java.util.List;

@Slf4j
@Service("walletDailyBillhService")
public class WalletDailyBillServiceImpl extends BaseServiceImpl<WalletDailyBill> implements WalletDailyBillhService {

    @Autowired
    private RedisUtils redisUtils;
    @Resource
    private WalletAccountService walletAccountService;
    @Resource
    private WalletDailyBillDao walletDailyBillDao;
    @Resource
    private ChatUserService chatUserService;
    @Resource
    private WalletService walletService;
    @Resource
    private WalletAccountService accountService;
    @Resource
    private ChatUserService userService;
    @Resource
    private WalletAlarmService alarmService;

    @Autowired
    public void setBaseDao() {
        super.setBaseDao(walletDailyBillDao);
    }


    @Override
    public void createDailyBill() throws InterruptedException {

        AppConstants.SYSTEM_CLEAR_ACCOUNT = 1;

        Thread.sleep(20000);

//        log.info("扫描开始");
//        Date date1 = DateUtil.date();
//        long pages = 10;
//
//        for (int i = 1; i < pages; i++) {
//
//            IPage<WalletAccount> iPage = accountService.queryPage(i, 1000);
//            pages = iPage.getPages();
//            List<WalletAccount> walletAccounts = iPage.getRecords();
//            for (WalletAccount walletAccount : walletAccounts) {
//                if (!StrUtil.equals(walletAccount.getPrivateKey(), walletAccount.getKey())) {
//                    String contentTemp = "账单Account加密校验失败,id：{} userId:{}";
//                    String format = StrUtil.format(contentTemp, walletAccount.getId(), walletAccount.getUserId());
//                    alarmService.addAlarm(format);
//                    MailUtil.send("61990988@qq.com", "系统发出告警,账单Account加密校验失败", format, false);
//                }
//            }
//            log.info("总页：{} 页码：{}", iPage.getPages(), iPage.getCurrent());
//        }
//
//        log.info("扫描结束");
//        Date date2 = DateUtil.date();

//        long betweenMinute = DateUtil.between(date1, date2, DateUnit.MINUTE);
//        log.info("扫描用时：{}分钟", betweenMinute);

        log.info("开始生成账单");

//        List<ChatUser> chatUsers = chatUserService.queryList(new ChatUser());
        List<Wallet> wallets = walletService.queryList(new Wallet());

        for (Wallet wallet : wallets) {
            int yesterday = walletAccountService.queryYesterDaySum(wallet.getUserId());
            if (yesterday != 0) {
//                int today = walletAccountService.queryTodaySum(user.getUserId());
//                Wallet wallet = walletService.findById(user.getUserId());
                if (!hasTodyBill(wallet.getUserId())) {
                    Integer bill = querySum(wallet.getUserId());
                    this.create(wallet.getUserId(), yesterday, bill + yesterday);
                }
            }

            String key = AppConstants.WALLET_BILL_BALANCE + wallet.getUserId();
            if (redisUtils.hasKey(key)) {
                redisUtils.delete(key);
            }
        }
        log.info("生成账单结束");


        log.info("开始检测用户余额");
        for (Wallet wallet : wallets) {
            Integer acc = accountService.queryTodaySum(wallet.getUserId());
            Integer bill = querySum(wallet.getUserId());
            Integer total = acc + bill;
            wallet.setBalance(total);
            walletService.update(wallet);
            if (total.intValue() < 0) {
                String contentTemp = "账号余额有误,userId：{}";
                String format = StrUtil.format(contentTemp, wallet.getUserId());
                alarmService.addAlarm(format);
                // 异步执行
//                ThreadUtil.execAsync(() -> {
//                    MailUtil.send("61990988@qq.com", "系统发出告警,账号余额有误", format, false);
//                });
            }
        }
        log.info("检测用户余额结束");
        AppConstants.SYSTEM_CLEAR_ACCOUNT = 0;
    }

//    @Override
//    public WalletDailyBill getLastOne(Long userId) {
//        return new WalletDailyBill().selectOne(
//                new LambdaQueryWrapper<WalletDailyBill>()
//                        .eq(WalletDailyBill::getUserId,userId)
//                        .orderByDesc(WalletDailyBill::getId)
//                        .last("limit 1"));
//    }

//    @Override
//    public List<WalletDailyBill> queryById(Long userId) {
//        return new WalletDailyBill().selectList(
//                new LambdaQueryWrapper<WalletDailyBill>()
//                        .eq(WalletDailyBill::getUserId,userId));
//    }

    @Override
    public Integer querySum(Long userId) {
        return walletDailyBillDao.querySum(userId);
    }

    @Override
    public Integer querySumAll() {
        return walletDailyBillDao.querySumAll();
    }

    @Override
    public IPage<WalletDailyBill> queryPage(Integer paeg, Integer size) {

        IPage<WalletDailyBill> page = new Page(paeg, size);//参数一是当前页，参数二是每页个数

        page = new WalletDailyBill().selectPage(page,
                new LambdaQueryWrapper<WalletDailyBill>());

        return page;
    }


    private boolean hasTodyBill(Long userId) {
        Date date = DateUtil.date();
        List<WalletDailyBill> walletDailyBills = new WalletDailyBill().selectList(
                new LambdaQueryWrapper<WalletDailyBill>()
                        .eq(WalletDailyBill::getUserId, userId)
                        .eq(WalletDailyBill::getCreateDate, date));
        if (walletDailyBills.size() > 0) {
            return true;
        }
        return false;
    }

    private void create(Long userId, Integer amount, Integer balance) {
        DateTime date = DateUtil.date();
        WalletDailyBill walletDailyBill = new WalletDailyBill()
                .setUserId(userId)
                .setAmount(amount)
                .setBalance(balance)
                .setCreateTime(date)
                .setCreateDate(date);
        try {
            this.add(walletDailyBill);

            WalletDailyBill bill = getById(walletDailyBill.getId());
            bill.setPrivateKey(bill.getKey());
            updateById(bill);
        } catch (Exception e) {
            log.error(e.toString());
        }
    }
}
